package weaver.jobs.camci;

import cfca.sadk.org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import weaver.conn.RecordSet;
import weaver.formmode.setup.ModeRightInfo;
import weaver.general.BaseBean;
import weaver.general.TimeUtil;
import weaver.general.Util;
import weaver.rsa.security.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author dusongsong
 * @date 2023年12月21日 14:15
 */
public class CamciUtil {

    private static BaseBean baseBean = new BaseBean();
    //APPID
    private static final String APPID = "614xc";
    //APPSECRET
    private static final String APPSECRET = "85errldds56assd";
    //请求地址
    private static final String URL = "http://financial.camci.com.cn/api/webTravel";
    //编码格式
    private static final String CHARSET_NAME = "UTF-8";
    // AES加密
    private static final String AES_NAME = "AES";
    // 加密模式
    private static final String ALGORITHM = "AES/CBC/PKCS7Padding";
    // 密钥
    private static final String SECRETKEY = "8db7fba29839424d";
    // 偏移量
    private static final String IV = "8db7fba29839424d";

    static {

        Security.addProvider(new BouncyCastleProvider());

    }

    /**
     * 加密
     *
     * @param content
     * @return
     */
    public static String encrypt(String content) {
        byte[] result = null;
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            SecretKeySpec keySpec = new SecretKeySpec(SECRETKEY.getBytes(CHARSET_NAME), AES_NAME);
            AlgorithmParameterSpec paramSpec = new IvParameterSpec(IV.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, paramSpec);
            result = cipher.doFinal(content.getBytes(CHARSET_NAME));
            baseBean.writeLog(">>>>>encrypt>>>SECRETKEY" + SECRETKEY);
            baseBean.writeLog(">>>>>encrypt>>>IV" + IV);
        } catch (Exception e) {
            baseBean.writeLog(">>>>>encrypt>>>加密失败" + Arrays.toString(result));
            e.printStackTrace();
        }
        return Base64.encodeBase64String(result);
    }

    /**
     * 获取签名
     *
     * @return
     */
    public static String getSign() {
        JSONObject paramJson = new JSONObject();
        paramJson.put("appId", APPID);
        paramJson.put("appSecret", APPSECRET);
        paramJson.put("timestamp", (System.currentTimeMillis() / 1000));
        String content = paramJson.toJSONString();// 原文信息
        System.out.println(">>>>>getSign>>>content" + content);
        return CamciUtil.encrypt(content);
    }

    /**
     * 请求处理器
     *
     * @param paramsJson
     * @return
     */
    public static JSONObject sendOKHttpRequest(JSONObject paramsJson) {
        JSONObject resultJson = new JSONObject();
        String code = "failure";
        String message = "";
        String data = "";
        try {
            OkHttpClient client = new OkHttpClient().newBuilder()
                    .connectTimeout(60, TimeUnit.SECONDS)
                    .readTimeout(60, TimeUnit.SECONDS)
                    .writeTimeout(60, TimeUnit.SECONDS)
                    .build();
            MediaType mediaType = MediaType.parse("application/json");
            RequestBody body = RequestBody.create(mediaType, paramsJson.toJSONString());
            Request request = new Request.Builder()
                    .url(URL)
                    .method("POST", body)
                    .addHeader("Content-Type", "application/json")
                    .build();
            Response response = client.newCall(request).execute();
            String result = Util.null2String(response.body().string());
            if (!"".equals(result)) {
                data = result;
                code = "success";
            } else {
                message = "response result is null";
            }
        } catch (Exception e) {
            message = "response timeout";
            e.printStackTrace();
        }
        resultJson.put("code", code);
        resultJson.put("data", data);
        resultJson.put("message", message);
        return resultJson;
    }

    /**
     * 字符串生成MD5
     *
     * @param plainText
     * @return
     */
    public static String stringToMD5(String plainText) {
        byte[] secretBytes = null;
        try {
            secretBytes = MessageDigest.getInstance("md5").digest(
                    plainText.getBytes());
        } catch (Exception e) {
            throw new RuntimeException("没有这个md5算法！");
        }
        String md5code = new BigInteger(1, secretBytes).toString(16);
        for (int i = 0; i < 32 - md5code.length(); i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }

    /**
     * 建模权限重构
     *
     * @param userid
     * @param formmodeid
     * @param id
     */
    private static void newModeRight(int userid, int formmodeid, int id) {
        ModeRightInfo modeRightInfo = new ModeRightInfo();
        modeRightInfo.setNewRight(true);
        modeRightInfo.editModeDataShare(userid, formmodeid, id);
    }

    /**
     * 将数据插入表单建模
     *
     * @param tablename
     * @param paramJson
     * @return
     */
    public static int insertModelData(String tablename, JSONObject paramJson) {
        int dataid = 0;
        RecordSet rs = new RecordSet();
        RecordSet rs1 = new RecordSet();
        //查询该模块表名
        int modeid = getFormmodeid(tablename);
        String uuid = UUID.randomUUID().toString();
        String insSql = "insert into " + tablename
                + "(modeuuid,modedatacreater,modedatacreatedate,modedatacreatetime,formmodeid)values(?,?,?,?,?)";
        Object[] params = {uuid, 1, TimeUtil.getCurrentDateString(), TimeUtil.getOnlyCurrentTimeString(), modeid};
        if (rs.executeUpdate(insSql, params)) {
            rs1.executeQuery("select id from " + tablename + " where modeuuid=?", uuid);
            rs1.next();
            dataid = Util.getIntValue(rs1.getString("id"));
            if (dataid > 0) {
                Map<String, Object> map = JSONObject.toJavaObject(paramJson, Map.class);
                //遍历数据 进行update
                String updatesql = "update " + tablename + " set ";
                Set<String> keySet = map.keySet();
                for (String key : keySet) {
                    updatesql += key + "='" + map.get(key) + "',";
                }
                if (updatesql.endsWith(",")) {
                    updatesql = updatesql.substring(0, updatesql.length() - 1);
                    updatesql += " where id=" + dataid;
                    rs.executeUpdate(updatesql);
                }
                baseBean.writeLog(">>>>>insertDetailData>>>>updatesql=" + updatesql);
                //进行权限重构
                newModeRight(1, modeid, dataid);
            }
        }
        return dataid;
    }

    /**
     * 更新明细数据
     *
     * @param tablename
     * @param paramJson
     * @return
     */
    public static boolean insertDetailData(String tablename, JSONObject paramJson) {
        String insertsql = "insert into " + tablename + "";
        String keyString = "";
        String valueString = "";
        Map<String, Object> map = JSONObject.toJavaObject(paramJson, Map.class);
        Set<String> keySet = map.keySet();
        for (String key : keySet) {
            keyString += key + ",";
            valueString += "'" + map.get(key) + "',";
        }
        if (keyString.endsWith(",")) {
            keyString = keyString.substring(0, keyString.length() - 1);
        }
        if (valueString.endsWith(",")) {
            valueString = valueString.substring(0, valueString.length() - 1);
        }
        insertsql += "(" + keyString + ") values(" + valueString + ")";
        baseBean.writeLog(">>>>>insertDetailData>>>>insertsql=" + insertsql);
        RecordSet rs = new RecordSet();
        return rs.executeUpdate(insertsql);
    }

    /**
     * 更新数据
     *
     * @param tablename 表名
     * @param paramJson 数据集合
     * @param dataid    更新用唯一标识
     * @return
     */
    public static boolean updateModelData(String tablename, int dataid, JSONObject paramJson) {
        RecordSet rs = new RecordSet();
        String updatesql = "update " + tablename + " set  ";
        String valuesStr = "";
        Map<String, Object> map = JSONObject.toJavaObject(paramJson, Map.class);
        Set<String> keySet = map.keySet();
        for (String key : keySet) {
            if (valuesStr.equals("")) {
                valuesStr = key + "='" + map.get(key) + "'";
            } else {
                valuesStr += "," + key + "='" + map.get(key) + "'";
            }
        }
        updatesql += valuesStr + " where id='" + dataid + "'";
        baseBean.writeLog(">>>>>updateModelData>>>>updatesql=" + updatesql);
        return rs.execute(updatesql);
    }


    /**
     * 获取建模Id
     *
     * @param tablename
     * @return
     */
    private static int getFormmodeid(String tablename) {
        RecordSet rs = new RecordSet();
        String sql = "select m.id from modeinfo m left join WORKFLOW_BILL b on m.formid = b.id where b.tablename = ?";
        rs.executeQuery(sql, tablename);
        rs.next();
        return Util.getIntValue(rs.getString("id"));
    }

    /**
     * 判断是否是JSON数组
     *
     * @param fieldvalue
     * @return
     */
    public static boolean isJSONArray(String fieldvalue) {
        boolean flag = false;
        if (!(fieldvalue.trim().equals(""))) {
            try {
                JSONArray.parseArray(fieldvalue);
                flag = true;
            } catch (Exception e) {
                flag = false;
            }
        }
        return flag;
    }

    /**
     * 拆分日期为每一天
     *
     * @param begindate
     * @param enddate
     * @return
     */
    public static List<LocalDate> splitByDateBetween(String begindate, String enddate) {
        //开始日期
        LocalDate beginDate = LocalDate.parse(begindate);
        //结束日期
        LocalDate endDate = LocalDate.parse(enddate);
        LocalDate date = beginDate;
        List<LocalDate> dates = new ArrayList<>();
        //遍历日期
        while (!date.equals(endDate.plusDays(1))) {
            dates.add(date);
            date = date.plusDays(1);
        }
        return dates;
    }

    /**
     * 删除数据
     *
     * @param tablename 表名
     * @param dataid    更新用唯一标识
     * @return
     */
    public static boolean deleteDetailData(String tablename, String dataid) {
        RecordSet rs = new RecordSet();
        String deletesql = "delete " + tablename + " where mainid='" + dataid + "'";
        baseBean.writeLog(">>>>>deleteDetailData>>>>deletesql=" + deletesql);
        return rs.executeUpdate(deletesql);
    }

    /**
     * @param loginid
     * @return
     */
    public static String getResourceidByLoginid(String loginid) {
        RecordSet rs = new RecordSet();
        rs.executeQuery("select id from hrmresource where loginid=?", loginid);
        rs.next();
        return Util.null2String(rs.getString(1));
    }

    /**
     * 判断是否重复
     *
     * @param userid
     * @param begindate
     * @param enddate
     * @return
     */
    public static JSONObject isExistResourceid(String userid, String tablename, String begindate, String enddate,String areas) {
        RecordSet rs = new RecordSet();
        JSONObject resultJson = new JSONObject();
        String status = "I";
        String mainid = "";
        String sql = "select mainid,qtdd,MAX(xcrq) maxxcrq,MIN(xcrq) minxcrq from " + tablename + " where bbr=? group by mainid,qtdd";
        rs.executeQuery(sql, userid);
        if (rs.next()) {
            mainid = Util.null2String(rs.getString("mainid"));
            String qtdd = Util.null2String(rs.getString("qtdd"));
            String maxxcrq = Util.null2String(rs.getString("maxxcrq"));
            String minxcrq = Util.null2String(rs.getString("minxcrq"));
            if(begindate.equals(minxcrq) && enddate.equals(maxxcrq) && areas.equals(qtdd)){
                status = "N";
            }else {
                status = "U";
            }
        }
        resultJson.put("mainid",mainid);
        resultJson.put("status",status);
        return resultJson;
    }

}
